iT邦幫忙

2022 iThome 鐵人賽

DAY 4
0

在昨天我們發現了,我們執行了很多重複的運算,下面的圖同樣的顏色就是同樣的數據.

https://github.com/officeyuli/itHome2022/raw/main/day3/day2.drawio%20(1).png

那有沒有辦法減少重複的計算呢.這就是我們今天的重點了,Memo.

當如果Momo裡面有已經計算過的子問題,就直接拿出來,就不用重新計算.

通常Momo都是使用Array來當作載體,也有使用HashMap的,可以根據題目來決定要使用哪種.

我們將昨天的程式碼稍微修改一下,讓在計算的時候帶著Memo.

fun fibonacciWithMemoVersion(n: Int): Int {
    return when (n) {
        0 -> {0}
        1 -> {1}
        else -> {
            val memoArray = IntArray(n+1)//建立Memo Array
            memoArray[0] = 0
            memoArray[1] = 1
            fibonacciWithMemoHelper(memoArray, n)
        }
    }
}

fun fibonacciWithMemoHelper(memoArray: IntArray, n: Int): Int {
    return when {
        n == 0 -> {
            0
        }
        memoArray[n] != 0 -> {//已經在Memo裡面有計算過了
            memoArray[n]
        }
        else -> {
            memoArray[n] =
                fibonacciWithMemoHelper(memoArray,n-1)+ fibonacciWithMemoHelper(memoArray,n-2)
            //計算新的數據
            memoArray[n]
        }
    }
}

讓我們來比較一下,利用measureTimeMillis來計算時間

fun main() {
    val n = 30
    println("N = $n")

    val timeCostNormal = measureTimeMillis {
        val ans = fibonacci(n)
        println("Normal version $ans")
    }

    val timeCostMomo = measureTimeMillis {
        val ans = fibonacciWithMemoVersion(n)
        println("Memo version $ans")
    }

    println("TimeCostNormal:$timeCostNormal")
    println("TimeCostMomo:$timeCostMomo")
}

先跑跑看n = 30

https://github.com/officeyuli/itHome2022/raw/main/day4/n30.jpg

普通版本花費時間是7秒,而Memo版本不到1秒

但在n = 40 的版本,差距就越發的明顯

https://github.com/officeyuli/itHome2022/raw/main/day4/n40.jpg

普通版本花費時間大幅上升,而Memo版本時間沒有增加.

為什麼有如此大的差距,因為Memo版本所有的子問題都只要計算一次.當計算後再次遇到同樣的子問題,就能省略.

也就因此,不再需要進行迴圈計算.

我們來計算時間複雜度,子問題的個數是f(0),f(1)....f(n) ,所以是O(N)

而解決一個子問題,只需要去Memo內拿取已經計算好的子問題答案,而若未計算的子問題,同樣也只需要計算一次,沒有迴圈計算,所以子問題的時間複雜度為O(1)

兩者相乘,使用Memo版本的複雜度降為了O(N),也難怪在N變大時,所花費的時間沒有什麼變化.比起暴力計算,花費低上許多.

今天我們使用了Memo來作為輔助.明天我們會來使用DP Table.


上一篇
Day 3: 費波那契數列
下一篇
Day 5: DP Table解法
系列文
從零開始的LeetCode生活,使用Kotlin學習刷題30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言